// TagBufferTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "../TagBuffer.h"

static const char * ta01 = "ta01";
static const char * ta02 = "ta02";
static const char * ta03 = "ta03";
static const char * ta04 = "ta04";
static const char * ta05 = "ta05";
static const char * ta06 = "ta06";
static const char * ta07 = "ta07";
static const char * ta08 = "ta08";
static const char * ta09 = "ta09";
static const char * ta10 = "ta10";
static const char * ta11 = "ta11";
static const char * ta12 = "ta12";
static const char * ta13 = "ta13";
static const char * ta14 = "ta14";
static const char * ta15 = "ta15";
static const char * ta16 = "ta16";
static const char * ta17 = "ta17";
static const char * ta18 = "ta18";
static const char * ta19 = "ta19";
static const char * ta20 = "ta20";
static const char * ta21 = "ta21";
static const char * ta22 = "ta22";

#define CHECK(X) if (X != RET_OK) return false;


// Test1: 
// Write byte, short, int24, int32, int64, int128.
// Read byte, short, int24, int32, int64, int128.
// Read int128, int64, int32, int24, short, byte.
// Read int32, !!![int32]!!!, int64, int24, byte, short, int128.
bool Test1()
{
	eResult res = RET_ERROR;
	tTagBuffer tagbuf;
	size_t bufsize = tTagBuffer::ByteTagSize() + \
		tTagBuffer::ShortTagSize() + \
		tTagBuffer::Int24TagSize() + \
		tTagBuffer::Int32TagSize() + \
		tTagBuffer::Int64TagSize() + \
		tTagBuffer::Int128TagSize();
	ALLOC(&tagbuf, bufsize);
	tagbuf.WriteTagByte(ta01, 1);
	tagbuf.WriteTagShort(ta02, 2);
	tagbuf.WriteTagInt24(ta03, 3);
	tagbuf.WriteTagInt32(ta04, 4);
	tagbuf.WriteTagInt64(ta05, 5);
	tagbuf.WriteTagInt128(ta06, 6);
	
	BYTE v1 = tagbuf.GetTagByte(ta01, &res);
	CHECK(res);
	USHORT v2 = tagbuf.GetTagShort(ta02, &res);
	CHECK(res);
	UINT v3 = tagbuf.GetTagInt24(ta03, &res);
	CHECK(res);
	UINT v4 = tagbuf.GetTagInt32(ta04, &res);
	CHECK(res);
	UINT64 v5 = tagbuf.GetTagInt64(ta05, &res);
	CHECK(res);
	tInt128 v6 = tagbuf.GetTagInt128(ta06, &res);
	CHECK(res);
	if (v1 != 1 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 5 || v6 != 6)
		return false;

	v6 = tagbuf.GetTagInt128(ta06, &res);
	v5 = tagbuf.GetTagInt64(ta05, &res);
	v4 = tagbuf.GetTagInt32(ta04, &res);
	v3 = tagbuf.GetTagInt24(ta03, &res);
	v2 = tagbuf.GetTagShort(ta02, &res);
	v1 = tagbuf.GetTagByte(ta01, &res);
	if (v1 != 1 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 5 || v6 != 6)
		return false;

	// Read int32, !!![int32]!!!, int64, int24, byte, short, int128.	
	v4 = tagbuf.GetTagInt32(ta04, &res);
	v4 = tagbuf.GetTagInt32(ta04, &res);
	v5 = tagbuf.GetTagInt64(ta05, &res);
	v3 = tagbuf.GetTagInt24(ta03, &res);
	v1 = tagbuf.GetTagByte(ta01, &res);
	v2 = tagbuf.GetTagShort(ta02, &res);
	v6 = tagbuf.GetTagInt128(ta06, &res);
	if (v1 != 1 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 5 || v6 != 6)
		return false;

	return true;
}

// Test2:
// Write Byte, Int32, Int24
// Read  Int128, Int32, Int64, Byte, Int24
// Read ta10, ta11, ta12
// Read Ta1, Ta2, ta3
bool Test2()
{
	eResult res = RET_ERROR;
	tTagBuffer tagbuf;
	size_t bufsize = tTagBuffer::ByteTagSize() + \
		tTagBuffer::Int32TagSize() + \
		tTagBuffer::Int24TagSize();
	ALLOC(&tagbuf, bufsize);
	tagbuf.WriteTagByte(ta01, 1);
	tagbuf.WriteTagInt32(ta02, 2);
	tagbuf.WriteTagInt24(ta03, 3);
	BYTE v1 = 0;
	UINT v2 = 0;
	UINT v3 = 0;
	UINT64 v4 = 0;
	tInt128 v5 = 0;
	
	v5 = tagbuf.GetTagInt128(ta01, &res);
	if (res == RET_OK)
		return false;
	

	v2 = tagbuf.GetTagInt32(ta02, &res);
	CHECK(res);

	v4 = tagbuf.GetTagInt64(ta01, &res);
	if(res == RET_OK)
		return false;

	v1 = tagbuf.GetTagByte(ta01, &res);
	CHECK(res);

	v3 = tagbuf.GetTagInt24(ta03, &res);
	CHECK(res);	

	if (v1 != 1 || v2 != 2 || v3 != 3)
		return false;

	tagbuf.GetTagByte(ta10, &res);
	if (res == RET_OK)
		return false;

	tagbuf.GetTagInt32(ta11, &res);
	if (res == RET_OK)
		return false;

	tagbuf.GetTagInt128(ta12, &res);
	if (res == RET_OK)
		return false;

	v1 = tagbuf.GetTagByte(ta01, &res);
	CHECK(res);

	v2 = tagbuf.GetTagInt32(ta02, &res);
	CHECK(res);

	v3 = tagbuf.GetTagInt24(ta03, &res);
	CHECK(res);	

	if (v1 != 1 || v2 != 2 || v3 != 3)
		return false;

	return true;
}

// Test3:
// Write Data[sizeof(256)], Int32, Int128
// Read  Int128, Int32, Data[sizeof(256)], Int128, Int32
// Read Data[sizeof(100)]
// Read Data[sizeof(256)] with tBuffer.

bool Test3()
{
	unsigned int bufsize = 256;
	unsigned char b[256];
	b[0] = 0xaf;
	b[5] = 0xaf;
	b[100] = 0xaf;
	b[255] = 0xaf;

	tTagBuffer tagbuf;
	size_t tagbufsize = tTagBuffer::DataTagSize(bufsize) + \
		tTagBuffer::Int32TagSize() + \
		tTagBuffer::Int128TagSize();
	ALLOC(&tagbuf, tagbufsize);

	tagbuf.WriteTagData(ta01, (PBYTE)b, bufsize);
	tagbuf.WriteTagInt32(ta02, 1);
	tagbuf.WriteTagInt128(ta03, 2);

	eResult Res = RET_ERROR;
	tInt128 v2 = tagbuf.GetTagInt128(ta03, &Res);
	CHECK(Res);
	UINT v1 = tagbuf.GetTagInt32(ta02, &Res);
	CHECK(Res);
	unsigned int datasize = tagbuf.GetTagDataSize(ta01, &Res);
	CHECK(Res);
	if (datasize != bufsize)
		return false;
	tagbuf.GetTagData(ta01, (PBYTE)b, datasize, &Res);
	CHECK(Res);
	if (b[0] != 0xaf || b[5] != 0xaf || b[100] != 0xaf || b[255] != 0xaf)
		return false;
	v2 = tagbuf.GetTagInt128(ta03, &Res);
	CHECK(Res);
	v1 = tagbuf.GetTagInt32(ta02, &Res);
	CHECK(Res);

	tagbuf.GetTagData(ta01, (PBYTE)b, 100, &Res);
	if (Res == RET_OK)
		return false;

	tStreamBuffer sb;
	tagbuf.GetTagBuffer(ta01, &sb, &Res);
	CHECK(Res);
	sb.GetData((PBYTE)b, bufsize);
	if (b[0] != 0xaf || b[5] != 0xaf || b[100] != 0xaf || b[255] != 0xaf)
		return false;
	v2 = tagbuf.GetTagInt128(ta03, &Res);
	CHECK(Res);
	v1 = tagbuf.GetTagInt32(ta02, &Res);
	CHECK(Res);
	return true;
}

// Test4:
// Write: Int32, embeded tag, Byte
// Read: embeded tag, Int32, Byte
bool Test4()
{
	tTagBuffer embedtag;
	unsigned char embed_data[32];
	embed_data[0] = 0xaf;
	embed_data[31] = 0xaf;
	
	tTagBuffer tagbuf;
	size_t s = tTagBuffer::Int32TagSize() + \
		tTagBuffer::DataTagSize(tTagBuffer::DataTagSize(32)) + \
		tTagBuffer::ByteTagSize();
	ALLOC(&tagbuf, s);

	tagbuf.WriteTagInt32(ta01, 1);
	tagbuf.WriteEmptyTagData(ta02, &embedtag, (unsigned int)tTagBuffer::DataTagSize(32));
	embedtag.WriteTagData(ta05, (PBYTE)embed_data, 32);
	tagbuf.WriteTagByte(ta03, 2);
	
	eResult res = RET_ERROR;
	tTagBuffer readbuf;
	tagbuf.GetTagBuffer(ta02, &readbuf, &res);
	CHECK(res);
	tStreamBuffer bf;
	readbuf.GetTagBuffer(ta05, &bf, &res);
	CHECK(res);
	bf.GetData((PBYTE)embed_data, 32);
	if (embed_data[0] != 0xaf || embed_data[31] != 0xaf)
		return false;

	UINT v1 = tagbuf.GetTagInt32(ta01, &res);
	CHECK(res);

	BYTE v3 = tagbuf.GetTagByte(ta03, &res);
	CHECK(res);

	return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (Test1())
		printf("Test 1 passed!\n");
	else
		printf("Test 1 failed!\n");
	if (Test2())
		printf("Test 2 passed!\n");
	else
		printf("Test 2 failed!\n");
	if (Test3())
		printf("Test 3 passed!\n");
	else
		printf("Test 3 failed!\n");
	if (Test4())
		printf("Test 4 passed!\n");
	else
		printf("Test 4 failed!\n");
	_getch();
	return 0;
}